home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
hity wydania
/
Ubuntu 9.10 PL
/
karmelkowy-koliberek-desktop-9.10-i386-PL.iso
/
casper
/
filesystem.squashfs
/
usr
/
bin
/
ubiquity-dm
< prev
next >
Wrap
Text File
|
2009-09-11
|
11KB
|
275 lines
#!/usr/bin/python
import os
import sys
import subprocess
import time
import signal
import errno
import imp
import grp
sys.path.insert(0, '/usr/lib/ubiquity')
import ubiquity.frontend
import pwd
from ubiquity import osextras
from ubiquity.casper import get_casper
background = '/usr/share/backgrounds/warty-final-ubuntu.png'
class XStartupError(EnvironmentError):
pass
class MissingProgramError(EnvironmentError):
pass
class DM:
def __init__(self, vt, display, default_username):
self.vt = vt
self.display = display
self.server_started = False
self.username = get_casper('USERNAME', default_username)
self.uid, self.gid = pwd.getpwnam(self.username)[2:4]
self.homedir = pwd.getpwnam(self.username)[5]
self.uid = int(self.uid)
self.gid = int(self.gid)
self.groups = []
for g in grp.getgrall():
if self.username in g[3] or g[0] == self.username:
self.groups.append(g[2])
# Look for a frontend module; we won't actually use it (yet), but
# this lets us find out which window manager etc. to launch. Be
# careful that importing this here will cause the underlying library
# to try to talk to the X server, which won't go well.
frontend_names = ['mythbuntu_ui', 'gtk_ui', 'kde_ui']
self.frontend = None
for f in frontend_names:
try:
imp.find_module(f, ubiquity.frontend.__path__)
self.frontend = f
break
except ImportError:
pass
else:
raise AttributeError, ('No frontend available; tried %s' %
', '.join(frontend_names))
def sigusr1_handler(self, signum, frame):
self.server_started = True
def drop_privileges(self):
os.setgroups(self.groups)
os.setgid(self.gid)
os.setuid(self.uid)
def server_preexec(self):
signal.signal(signal.SIGUSR1, signal.SIG_IGN)
def run(self, *program):
null = open('/dev/null', 'w')
if not os.path.exists('/var/log/installer'):
os.makedirs('/var/log/installer')
logfile = open('/var/log/installer/dm', 'w')
signal.signal(signal.SIGUSR1, self.sigusr1_handler)
signal.signal(signal.SIGTTIN, signal.SIG_IGN)
signal.signal(signal.SIGTTOU, signal.SIG_IGN)
servercommand = ['X', '-br', '-ac', '-noreset', self.vt, self.display]
if self.frontend == 'mythbuntu_ui':
servercommand.append('-dpi')
servercommand.append('100')
server = subprocess.Popen(servercommand, stdin=null, stdout=logfile, stderr=logfile, preexec_fn=self.server_preexec)
os.environ['DISPLAY'] = self.display
os.environ['HOME'] = self.homedir
# Really we should select on a pipe or something, but it's not worth
# the effort for now.
timeout = 60
while not self.server_started:
status = server.poll()
if type(status) is int and status != 0:
raise XStartupError, "X server exited with return code " + str(status)
if timeout == 0:
raise XStartupError, "X server failed to start after 60 seconds"
time.sleep(1)
timeout -= 1
# Session bus, apparently needed by most interfaces now
if ('DBUS_SESSION_BUS_ADDRESS' not in os.environ and
osextras.find_on_path('dbus-launch')):
dbus_subp = subprocess.Popen(
['dbus-launch', '--exit-with-session'],
stdin=null, stdout=subprocess.PIPE, stderr=logfile,
preexec_fn=self.drop_privileges)
for line in dbus_subp.stdout:
try:
name, value = line.rstrip('\n').split('=', 1)
os.environ[name] = value
except ValueError:
pass
dbus_subp.wait()
gconfd_running = False
if ((self.frontend == 'gtk_ui' or self.frontend == 'mythbuntu_ui') and
osextras.find_on_path('gconftool-2')):
subprocess.call(['gconftool-2', '--spawn'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
gconfd_running = True
extras = []
if self.frontend == 'gtk_ui' or self.frontend == 'mythbuntu_ui':
gconf_dir = ('xml:readwrite:%s' %
os.path.expanduser('~%s/.gconf' %
self.username))
accessibility = 'false'
if osextras.find_on_path('gconftool-2'):
subprocess.call(
['gconftool-2', '--config-source', gconf_dir,
'--type', 'int', '--set',
'/apps/metacity/general/num_workspaces', '1'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
subp = subprocess.Popen(
['gconftool-2', '--config-source', gconf_dir,
'--get', '/desktop/gnome/interface/accessibility'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
preexec_fn=self.drop_privileges)
accessibility = subp.communicate()[0].rstrip('\n')
# Accessibility infrastructure
if accessibility == 'true':
if os.path.exists('/usr/lib/at-spi/at-spi-registryd'):
extras.append(subprocess.Popen(['/usr/lib/at-spi/at-spi-registryd'],
stdin=null, stdout=logfile, stderr=logfile))
os.environ['GTK_MODULES'] = 'gail:atk-bridge'
maybe_drop_privileges = {}
if accessibility != 'true':
maybe_drop_privileges['preexec_fn'] = self.drop_privileges
# Don't show the background image in v1 accessibility profile. It
# is not shown in the GNOME desktop after all.
fp = open('/proc/cmdline', 'r')
if os.access(background, os.R_OK) and not 'access=v1' in fp.readline():
import gtk
pixbuf = gtk.gdk.pixbuf_new_from_file(background)
root = gtk.gdk.get_default_root_window()
(root_width, root_height) = root.get_size()
scaled = pixbuf.scale_simple(root_width, root_height, gtk.gdk.INTERP_BILINEAR)
(pixmap, mask) = scaled.render_pixmap_and_mask(0)
root.set_back_pixmap(pixmap, False)
root.clear()
gtk.gdk.flush()
fp.close()
if self.frontend in ('gtk_ui', 'mythbuntu_ui'):
if gconfd_running and osextras.find_on_path('metacity'):
wm = subprocess.Popen(['metacity', '--sm-disable'],
stdin=null, stdout=logfile, stderr=logfile,
**maybe_drop_privileges)
elif osextras.find_on_path('xfwm4'):
wm = subprocess.Popen('xfwm4',
stdin=null, stdout=logfile, stderr=logfile,
**maybe_drop_privileges)
elif osextras.find_on_path('matchbox-window-manager'):
wm = subprocess.Popen('matchbox-window-manager',
stdin=null, stdout=logfile, stderr=logfile,
**maybe_drop_privileges)
else:
raise MissingProgramError, \
"No window manager found (tried metacity, xfwm4, matchbox-window-manager)"
if os.path.exists('/usr/lib/gnome-settings-daemon/gnome-settings-daemon'):
extras.append(subprocess.Popen(['/usr/lib/gnome-settings-daemon/gnome-settings-daemon'],
stdin=null, stdout=logfile, stderr=logfile, **maybe_drop_privileges))
# Accessibility tools
if accessibility == 'true':
fp = open('/proc/cmdline', 'r')
if 'access=m2' in fp.readline():
if osextras.find_on_path('onboard'):
extras.append(subprocess.Popen(['onboard'],
stdin=null, stdout=logfile, stderr=logfile))
else:
if osextras.find_on_path('orca'):
time.sleep(15)
extras.append(subprocess.Popen(['orca', '-sudo', self.username, '-n'],
stdin=null, stdout=logfile, stderr=logfile))
fp.close()
elif self.frontend == 'kde_ui':
extras.append(subprocess.Popen(['kwriteconfig', '--file', 'kwinrc', '--group', 'Compositing', '--key', 'Enabled', 'false'], stdin=null, stdout=logfile, stderr=logfile, preexec_fn=self.drop_privileges))
wm = subprocess.Popen('kwin', stdin=null, stdout=logfile,
stderr=logfile, preexec_fn=self.drop_privileges)
greeter = subprocess.Popen(program, stdin=null, stdout=logfile, stderr=logfile)
ret = greeter.wait()
def kill_if_exists(pid, signum):
try:
os.kill(pid, signum)
except OSError, e:
if e.errno != errno.ESRCH:
raise
def sigalrm_handler(signum, frame):
kill_if_exists(wm.pid, signal.SIGKILL)
for extra in extras:
kill_if_exists(extra.pid, signal.SIGKILL)
kill_if_exists(wm.pid, signal.SIGTERM)
for extra in extras:
kill_if_exists(extra.pid, signal.SIGTERM)
if gconfd_running:
subprocess.call(['gconftool-2', '--shutdown'],
stdin=null, stdout=logfile, stderr=logfile,
preexec_fn=self.drop_privileges)
signal.signal(signal.SIGALRM, sigalrm_handler)
signal.alarm(1) # low patience with WMs failing to exit on demand
processes = set(extras)
processes.add(wm)
while processes:
done = set()
for process in processes:
try:
process.wait()
done.add(process)
except OSError, e:
if e.errno == errno.EINTR:
continue
raise
processes -= done
signal.alarm(0)
kill_if_exists(server.pid, signal.SIGTERM)
server.wait()
if ret is not None and ret >= 0:
return ret
else:
return 1
if len(sys.argv) < 4:
sys.stderr.write('Usage: %s <vt[1-N]> <:[0-N]> <username> <program> [<arguments>]\n' % sys.argv[0])
sys.exit(1)
vt, display, username = sys.argv[1:4]
try:
dm = DM(vt, display, username)
except XStartupError:
sys.exit(1)
proc = None
if dm.frontend == 'gtk_ui' or dm.frontend == 'mythbuntu_ui':
proc = ['/etc/init.d/gdm', 'start']
elif dm.frontend == 'kde_ui':
proc = ['/etc/init.d/kdm', 'start']
ret = dm.run(*sys.argv[4:])
if proc:
subprocess.Popen(proc)
sys.exit(ret)